package com.jubaozan.framework.sentinel.stat.init;


import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.FileCopyUtils;

/**
 * @author jiangjinwu
 * @version 1.0
 * @since 2025/7/28 18:51
 */

@Slf4j
@Component
public class SqlScriptExecutor implements CommandLineRunner {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    // SQL文件目录（默认classpath下的sql目录）
    private String sqlLocation ="init.sql/*.sql";

    @Override
    public void run(String... args) throws Exception {
        log.info("开始执行SQL脚本目录: {}", sqlLocation);

        // 1. 获取资源解析器
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

        // 2. 扫描指定目录下的所有SQL文件
        Resource[] resources = resolver.getResources(sqlLocation);

        if (resources.length == 0) {
            log.info("未发现需要执行的SQL文件");
            return;
        }

        // 3. 按文件名排序（可选，确保执行顺序）
        List<Resource> sortedResources = sortResources(resources);

        // 4. 逐个执行SQL文件
        for (Resource resource : sortedResources) {
            executeSqlFile(resource);
        }

        log.info("所有SQL脚本执行完成，共执行 {} 个文件", resources.length);
    }

    /**
     * 按文件名排序资源（如V1__init.sql, V2__add_column.sql）
     */
    private List<Resource> sortResources(Resource[] resources) {
        List<Resource> resourceList = new ArrayList<>();
        for (Resource resource : resources) {
            resourceList.add(resource);
        }

        // 按文件名自然排序
        resourceList.sort(Comparator.comparing(resource -> {
            try {
                return resource.getFilename();
            } catch (Exception e) {
                return "";
            }
        }));
        return resourceList;
    }

    /**
     * 执行单个SQL文件
     */
    private void executeSqlFile(Resource resource) {
        try {
            String fileName = resource.getFilename();
            log.info("开始执行SQL文件: {}", fileName);

            // 读取SQL文件内容
            byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream());
            String sql = new String(bytes, StandardCharsets.UTF_8);

            // 执行SQL（支持多语句，按;分割）
            String[] sqlStatements = sql.split(";");
            for (String statement : sqlStatements) {
                String trimmed = statement.trim();
                if (!trimmed.isEmpty()) {
                    jdbcTemplate.execute(trimmed);
                }
            }

            log.info("SQL文件执行成功: {}", fileName);
        } catch (Exception e) {
            log.error("执行SQL文件失败", e);
            throw new RuntimeException("SQL脚本执行失败", e);
        }
    }
}
